from math import *

# Node for each location
# each node gets a unique number via genNum
# neighbors are to the N,E,S,W; stored by their node numbers
# image is the visual identifier of the location; some locations
#     do not have images, are only along the path to other locations
class worldNode:
    def __init__(self,num,N,E,S,W,image):
        self.__num = num
        self.__N = N
        self.__E = E
        self.__S = S
        self.__W = W
        self.__image = image

    def set_name(self,num):
        self.__num = num

    def set_N(self,N):
        self.__N = N

    def set_E(self,E):
        self.__E = E

    def set_S(self,S):
        self.__S = S

    def set_W(self,W):
        self.__W = w

    def set_image(self,image):
        self.__image = image

    def get_num(self):
        return self.__num

    def get_N(self):
        return self.__N

    def get_E(self):
        return self.__E

    def get_S(self):
        return self.__S

    def get_W(self):
        return self.__W

    def get_image(self):
        return self.__image

# Node for simMyro
#  loc - keeps track of simMyro's current location
#  facing - keeps track of direction in which simMyro is facing
#  seeing - is a copy of the image simMryo sees at this that location
#  gazing - is a copy of the image simMryo sees in the direction it is facing
class aSimMyro:
    def __init__(self,loc, facing, seeing, gazing):
        self.__loc = loc
        self.__facing = facing
        self.__seeing = seeing
        self.__gazing = gazing

    def set_loc(self,loc):
        self.__loc = loc

    def set_facing(self,facing):
        self.__facing = facing

    def set_seeing(self,seeing):
        self.__seeing = seeing

    def set_gazing(self,gazing):
        self.__gazing = gazing

    def get_loc(self):
        return self.__loc

    def get_facing(self):
        return self.__facing

    def get_seeing(self):
        return self.__seeing

    def get_gazing(self):
        return self.__gazing

def setWorld():
    return "To be written"

def init():
    callsToInit += 1
    if callsToInit > 1:
        return "Error - init can only be called once"
    else:
        return simMyro.get_seeing(),simMyro.get_gazing()

def go(dist):
    newLoc = getNewLoc(dist)
    if newLoc:
        simMyro.set_loc(newLoc)
        see = world[newLoc].get_image()
        simMyro.set_seeing(see)
        gaze = getGazing(newLoc,simMyro.get_facing())
        simMyro.set_gazing(gaze)
        return [see,gaze]
    else:
        return False

def R90():
    direction = simMyro.get_facing()
    if direction == "N":
        direction = "E"
    elif direction == "E":
        direction = "S"
    elif direction == "S":
        direction = "W"
    elif direction == "W":
        direction = "N"
    else:
        print "ERROR - direction not NSEW"
    simMyro.set_facing(direction)
    gaze = getGazing(simMyro.get_loc(),direction)
    simMyro.set_gazing(gaze)
    return gaze

def L90():
    direction = simMyro.get_facing()
    if direction == "N":
        direction = "W"
    elif direction == "W":
        direction = "S"
    elif direction == "S":
        direction = "E"
    elif direction == "E":
        direction = "N"
    else:
        print "ERROR - direction not NSEW"
    simMyro.set_facing(direction)
    gaze = getGazing(simMyro.get_loc(),direction)
    simMyro.set_gazing(gaze)
    return gaze

def getNewLoc(dist):
    direction = simMyro.get_facing()
    loc = simMyro.get_loc()
    while type(loc) == intType and dist > 0:
        dist -= 1
        loc = getNeighbor(loc,direction)
    if type(loc) == intType:
        return loc
    else:
        return False

def getNeighbor(loc,direction):
    if direction == "N":
        return world[loc].get_N()
    elif direction == "E":
        return world[loc].get_E()
    elif direction == "S":
        return world[loc].get_S()
    elif direction == "W":
        return world[loc].get_W()
    else:
        print "ERROR - direction not NSEW"
        return False

def getGazing(loc,direction):
    neighbor = getNeighbor(loc,direction)
    imageHere = world[neighbor].get_image()
    if imageHere:
        return halve2(imageHere)
    else:
        return halve2(getGazing(neighbor,direction))

# Turns myro.graphics.Picture into one half the size with white space taking up
#   remainder
def halve2(p):
    w = 256
    h = 192
    newP = makePicture(w,h)
    tempP = makePicture(w,h)
    for rpx in range(w):
        offset = hgt/4
        for cpx in range(0,h,2):
            pixel1 = getPixel(p,rpx,cpx)
            r1,g1,b1 = getRGB(pixel1)
            pixel2 = getPixel(p,rpx,cpx+1)
            r2,g2,b2 = getRGB(pixel2)
            nupixel = getPixel(tempP,rpx,offset+cpx/2)
            nur = round((r1+r2+0.0)/2)
            nug = round((g1+g2+0.0)/2)
            nub = round((b1+b2+0.0)/2)            
            setRGB(nupixel,(nur,nug,nub))
    for cpx in range(hgt):
        offset = w/4
        for rpx in range(0,w,2):
            pixel1 = getPixel(tempP,rpx,cpx)
            r1,g1,b1 = getRGB(pixel1)
            pixel2 = getPixel(tempP,rpx+1,cpx)
            r2,g2,b2 = getRGB(pixel2)
            nupixel = getPixel(newP,offset+rpx/2,cpx)
            nur = round((r1+r2+0.0)/2)
            nug = round((g1+g2+0.0)/2)
            nub = round((b1+b2+0.0)/2)            
            setRGB(nupixel,(nur,nug,nub))
    return newP

# Turns myro.graphics.Picture into one half the size with white space taking up
#   remainder
def halve(p,hp,w,hgt):
    tempP = makePicture(w,hgt)
    for rpx in range(w):
        offset = hgt/4
        for cpx in range(0,hgt,2):
            pixel1 = getPixel(p,rpx,cpx)
            r1,g1,b1 = getRGB(pixel1)
            pixel2 = getPixel(p,rpx,cpx+1)
            r2,g2,b2 = getRGB(pixel2)
            nupixel = getPixel(tempP,rpx,offset+cpx/2)
            nur = round((r1+r2+0.0)/2)
            nug = round((g1+g2+0.0)/2)
            nub = round((b1+b2+0.0)/2)            
            setRGB(nupixel,(nur,nug,nub))
    for cpx in range(hgt):
        offset = w/4
        for rpx in range(0,w,2):
            pixel1 = getPixel(tempP,rpx,cpx)
            r1,g1,b1 = getRGB(pixel1)
            pixel2 = getPixel(tempP,rpx+1,cpx)
            r2,g2,b2 = getRGB(pixel2)
            nupixel = getPixel(hp,offset+rpx/2,cpx)
            nur = round((r1+r2+0.0)/2)
            nug = round((g1+g2+0.0)/2)
            nub = round((b1+b2+0.0)/2)            
            setRGB(nupixel,(nur,nug,nub))
